import dash
from dash import Input, Output, State, callback_context, html, dcc, ALL # 引入 ALL
import dash_bootstrap_components as dbc # 引入 dbc
from flask import current_app
from models import db, RepairRecord, Organization, Department,Product # 引入所需模型
from server import server # 假设你的 Flask app 实例名为 server
from datetime import datetime
import pandas as pd
import base64
import io
import os,time
from pprint import pprint # 引入 pprint 方便打印
from sqlalchemy.orm.attributes import InstrumentedAttribute # 用于序列化
from modules.generatelogs.generatelogs import write_repair_log
from flask import session
from models import User



# --- 新增：创建详细信息布局的辅助函数 ---
def object_as_dict(obj):
    """将 SQLAlchemy 对象转换为字典，处理日期时间等"""
    data = {}
    for c in obj.__table__.columns:
        value = getattr(obj, c.name)
        if isinstance(value, (datetime, pd.Timestamp)):
            data[c.name] = value.isoformat() # 或者使用 strftime
        elif isinstance(value, InstrumentedAttribute): # 跳过关系等属性
             continue
        else:
            data[c.name] = value
    # 你可能还需要手动添加关联对象的信息，如果需要的话
    # 例如: data['org_name'] = obj.organization.name if obj.organization else 'N/A'
    return data

# (将 handle_respond_action 等回调中重复的表格加载逻辑提取出来)
def reload_table_data(page_current, page_size, sort_by, org_shortname, dept_name,
                      status_filter, start_date, end_date, keyword):
    print("--- reload_table_data called ---") # 新增打印
    data = []
    page_count = 0
    try:
        with server.app_context():
            query = db.session.query(RepairRecord).filter(RepairRecord.is_active == 1)
            # 应用筛选条件 (与 update_repair_table 相同)
            if org_shortname: # 修改前
                query = query.filter(RepairRecord.org_shortname_c == org_shortname)
            # 修改后
            if isinstance(org_shortname, list):
                org_shortname = org_shortname[0] if org_shortname else ''
            query = query.filter(RepairRecord.org_shortname_c == org_shortname)
            if dept_name: query = query.filter(RepairRecord.department_name == dept_name)
            if status_filter: query = query.filter(RepairRecord.repair_status == status_filter)
            if start_date: query = query.filter(RepairRecord.report_date >= start_date)
            if end_date:
                end_date_dt = datetime.strptime(end_date, '%Y-%m-%d').date() + pd.Timedelta(days=1)
                query = query.filter(RepairRecord.report_date < end_date_dt)
            if keyword:
                search_term = f"%{keyword}%"
                query = query.filter(
                    (RepairRecord.product_name.like(search_term)) |
                    (RepairRecord.product_code.like(search_term)) |
                    (RepairRecord.fault_description.like(search_term))
                )
            # 排序 (与 update_repair_table 相同)
            if sort_by:
                for sort_item in sort_by:
                    col_id = sort_item['column_id']
                    if col_id in ['product_name', 'product_code', 'shortname_c', 'department_name', 'report_date', 'repair_status', 'repair_person']:
                        direction = sort_item['direction']
                        col = getattr(RepairRecord, col_id)
                        query = query.order_by(col.asc() if direction == 'asc' else col.desc())
            else:
                query = query.order_by(RepairRecord.report_date.desc())
            # 分页 (与 update_repair_table 相同)
            total_records = query.count()
            page_count = (total_records + page_size - 1) // page_size if page_size > 0 else 1
            records = query.offset(page_current * page_size).limit(page_size).all()
            # 格式化 (与 update_repair_table 相同)
            for r in records:
                data.append({
                    'product_id': r.product_id, 'product_name': r.product_name, 'product_code': r.product_code,
                    'org_shortname': r.org_shortname_c, 'department_name': r.department_name,
                    'report_date': r.report_date.strftime('%Y-%m-%d %H:%M:%S') if r.report_date else '',
                    'repair_status': r.repair_status, 'repair_person': r.repair_person,
                    # 'actions': generate_action_buttons(r.id, r.repair_status) # 暂时注释
                })
            print(f"p83 Reloaded {len(data)} records, total pages: {page_count}") # 新增打印
    except Exception as e:
        print(f"!!! ERROR in reload_table_data: {e}") # 新增打印
        import traceback
        traceback.print_exc() # 打印详细堆栈
        data = []
        page_count = 0
    return data, page_count


def create_details_layout(record_dict):
    """
    根据 RepairRecord 字典构建详细信息布局，字段名用 comment，每行显示两个字段，长文本自动换行。
    按钮状态根据 repair_status 动态切换
    """
    if not record_dict:
        return html.P("请在中间列表中选择一条维修记录查看详细信息。", className="text-muted mt-4")

    # 获取字段 comment 映射
    field_comments = {}
    for c in RepairRecord.__table__.columns:
        field_comments[c.name] = c.comment or c.name

    # 生成所有字段的显示项，每行两个
    fields = list(record_dict.items())
    rows = []
    for i in range(0, len(fields), 2):
        row_fields = []
        if i < len(fields):
            k, v = fields[i]
            label = field_comments.get(k, k)
            row_fields.append(
                dbc.Col(
                    html.Div([
                        html.Strong(f"{label}: "),
                        html.Span(str(v) if v is not None else "", style={"wordBreak": "break-word"})
                    ], style={"marginBottom": "0.5rem", "paddingLeft": "5px"}),
                    width=6
                )
            )
        if i + 1 < len(fields):
            k, v = fields[i + 1]
            label = field_comments.get(k, k)
            row_fields.append(
                dbc.Col(
                    html.Div([
                        html.Strong(f"{label}: "),
                        html.Span(str(v) if v is not None else "", style={"wordBreak": "break-word"})
                    ], style={"marginBottom": "0.5rem", "paddingLeft": "5px"}),
                    width=6
                )
            )
        rows.append(dbc.Row(row_fields, className="mb-2"))

    # 按钮状态判断
    repair_status = record_dict.get('repair_status')
    return html.Div([
        dcc.Store(id='repair-details-record-id-store', data=record_dict.get('id')),
        html.Div([
            html.Div(rows, style={"width": "100%"})
        ], className="detail-section mb-3", style={"paddingLeft": "5px"}),
        # 移除以下按钮代码块
        # html.Div([
        #     dbc.Button("维修响应", id="repair-respond-button", color="success", className="me-1 mt-2 btn-sm",
        #                disabled=not (repair_status == '待响应'), n_clicks=0),
        #     dbc.Button("维修完成", id="repair-complete-button", color="primary", className="me-1 mt-2 btn-sm",
        #                disabled=not (repair_status == '维修中'), n_clicks=0),
        #     dbc.Button("工单", id="upload-proof-btn", color="info", className="me-1 mt-2 btn-sm",
        #                disabled= not (repair_status in ['维修中', '已修复', '维修完成','已完成']), n_clicks=0),
        #     dbc.Button("取消维修", id="repair-order-cancel", color="danger", className="mt-2 btn-sm",
        #                disabled=not (repair_status in ['待响应', '维修中','未完成','已取消']), n_clicks=0),
        # ], className="mt-3 text-end detail-actions")
    ], style={'maxHeight': 'calc(100vh - 150px)', 'overflowY': 'auto', 'paddingLeft': '10px'})


# --- 回调注册 ---
def register_repair_callbacks(dash_app):

    # --- 注册 Modal 相关回调 ---
    # register_modal_callbacks(dash_app) # 调用 modals.py 中的注册函数

    # --- 动态加载机构选项 (用于筛选和新增Modal) ---
    @dash_app.callback(
        Output('repair-org-filter', 'options'),
        Output('new-repair-org', 'options'), # <--- 同时更新新增Modal的机构选项
        Input('repair-org-filter', 'id') # 使用一个固定的 Input 来触发加载
    )
    def load_org_options(trigger_id):
        # print("--- load_org_options triggered ---")
        options = [{'label': '所有机构', 'value': ''}] # 筛选器的默认选项
        new_repair_options = [] # 新增Modal没有"所有机构"
        
        # 从session中获取当前用户的org_code
        user_org_code = session.get('user_org_code')
        # print(f"当前用户org_code: {user_org_code}") # 添加调试信息
        
        try:
            with server.app_context():
                # 如果用户不是HPQWJW（黄浦区卫健委），则只能看到自己机构的选项
                if user_org_code and user_org_code.upper() != 'HPQWJW':
                    # 通过 user_org_code 查询 Organization 表获取 short_name_c
                    org_obj = db.session.query(Organization).filter(Organization.org_code == user_org_code).first()
                    if org_obj and org_obj.short_name_c:
                        # 只添加用户所属机构的选项
                        org_opts = [{'label': org_obj.short_name_c, 'value': org_obj.short_name_c}]
                        options.extend(org_opts)
                        new_repair_options.extend(org_opts)
                        # print(f"用户 {user_org_code} 只能看到机构: {org_obj.short_name_c}")
                else:
                    # HPQWJW用户可以看到所有机构
                    orgs = db.session.query(Organization).filter(Organization.is_active == 1).order_by(Organization.short_name_c).all()
                    if orgs:
                        org_opts = [{'label': org.short_name_c, 'value': org.short_name_c} for org in orgs if org.short_name_c]
                        options.extend(org_opts)
                        new_repair_options.extend(org_opts) # 新增Modal使用相同的选项
                        # print(f"HPQWJW用户可以看到所有机构: {len(org_opts)}个")
                    else:
                        print("No active organizations found.")
        except Exception as e:
            print(f"!!! ERROR in load_org_options: {e}")
        
        print(f"返回的机构选项数量: {len(options)-1}") # -1是因为有一个'所有机构'选项
        return options, new_repair_options

    # --- 动态加载科室选项 (用于筛选) ---
    @dash_app.callback(
        Output('repair-dept-filter', 'options'),
        
        Output('repair-dept-filter', 'value'), # 清空已选值
        Output('repair-dept-filter', 'disabled'), # 控制是否禁用
        Input('repair-org-filter', 'value') # 监听机构选择的变化
    )
    def load_dept_options(selected_org_shortname):
        dept_options = []
        is_disabled = True
    
        # 添加类型检查
        if isinstance(selected_org_shortname, list):
            selected_org_shortname = selected_org_shortname[0] if selected_org_shortname else ''
    
        if not selected_org_shortname:
            return dept_options, '', is_disabled
    
        try:
            with server.app_context():
               
                depts = db.session.query(RepairRecord.department_name)\
                                  .filter(RepairRecord.org_shortname_c == selected_org_shortname)\
                                  .distinct()\
                                  .order_by(RepairRecord.department_name)\
                                  .all()

             


                # print(f"Found {len(depts)} departments for org '{selected_org_shortname}'.")
                if depts:
                    dept_options.extend([{'label': dept[0], 'value': dept[0]} for dept in depts if dept[0]])
                    is_disabled = False # 查询到科室，启用下拉框
                else:
                    print(f"No departments found for org '{selected_org_shortname}'.")
                    # 即使没有科室，也启用下拉框，但只显示“所有科室”
                    is_disabled = False

        except Exception as e:
            print(f"!!! ERROR in load_dept_options: {e}")
            # 出错时保持禁用

        # print(f"Returning options for repair-dept-filter: {dept_options}, disabled: {is_disabled}")
        return dept_options, '', is_disabled # 返回选项、清空值、是否禁用

   

    # # --- 更新维修记录表格 ---
    # @dash_app.callback(
    #     [Output('repair-records-table', 'data'),
    #     Output('repair-records-table', 'page_count'),
    #     Output('repair-respond-button', 'disabled', allow_duplicate=True),
    #     Output('repair-complete-button', 'disabled'),
    #     Output('upload-proof-btn', 'disabled')],
    #     [Input('repair-records-table', "page_current"),
    #     Input('repair-records-table', "page_size"),
    #     Input('repair-records-table', "sort_by"),
    #     Input('repair-org-filter', 'value'),
    #     Input('repair-dept-filter', 'value'),
    #     Input('repair-id-filter', 'value'),
    #     Input('repair-status-filter', 'value'),
    #     Input('repair-date-filter', 'start_date'),
    #     Input('repair-date-filter', 'end_date'),
    #     Input('repair-keyword-filter', 'value'),
    #     Input('repair-person-filter', 'value'),
    #     Input('repair-caller-filter', 'value'),
    #     Input('repair-filter-button', 'n_clicks'),
    #     Input('repair-refresh-flag-answer', 'data'),
    #     Input('repair-refresh-flag-complete', 'data'),
    #     Input('repair-refresh-flag-addnew', 'data'),
    #     Input('repair-refresh-flag-cancel', 'data'),
    #     Input('repair-records-table', 'active_cell'),
    #     State('repair-records-table', 'data')],
    #     prevent_initial_call='initial_duplicate'
    # )
    # def update_repair_table_and_buttons(page_current, page_size, sort_by,
    #                     org_shortname, dept_name, equipmentID, status_filter, start_date, end_date, keyword, repair_person, repair_caller, n_clicks, refresh_flag, refresh_flag2, refresh_flag3, refresh_flag4, active_cell, table_data):
    #     data = []
    #     page_count = 0
    #     disabled1 = disabled2 = disabled3 = True
    #     try:
    #         with server.app_context():
    #             query = db.session.query(RepairRecord).filter(RepairRecord.is_active == 1)
    #             from flask import session
    #             user_org_code = session.get('user_org_code')
    #             if user_org_code and user_org_code != 'HPQWJW':
    #                 org_obj = Organization.query.filter_by(org_code=user_org_code).first()
    #                 if org_obj and org_obj.short_name_c:
    #                     query = query.filter(RepairRecord.org_shortname_c == org_obj.short_name_c)
    #             if org_shortname:
    #                 if isinstance(org_shortname, list):
    #                     org_shortname = org_shortname[0] if org_shortname else ''
    #                 query = query.filter(RepairRecord.org_shortname_c == org_shortname)
    #             if dept_name:
    #                 if isinstance(dept_name, list):
    #                     dept_name = dept_name[0] if dept_name else ''
    #                 query = query.filter(RepairRecord.department_name == dept_name)
    #             if equipmentID:
    #                 query = query.filter(RepairRecord.product_id == equipmentID)
    #             if status_filter:
    #                 query = query.filter(RepairRecord.repair_status == status_filter)
    #             if start_date:
    #                 query = query.filter(RepairRecord.report_date >= start_date)
    #             if end_date:
    #                 end_date_dt = datetime.strptime(end_date, '%Y-%m-%d').date() + pd.Timedelta(days=1)
    #                 query = query.filter(RepairRecord.report_date < end_date_dt)
    #             if keyword:
    #                 search_term = f"%{keyword}%"
    #                 query = query.filter(
    #                     (RepairRecord.product_name.like(search_term)) |
    #                     (RepairRecord.product_code.like(search_term)) |
    #                     (RepairRecord.fault_description.like(search_term))
    #                 )
    #             if repair_person:
    #                 if isinstance(repair_person, list):
    #                     repair_person_value = repair_person[0] if repair_person else None
    #                 else:
    #                     repair_person_value = repair_person
    #                 if repair_person_value:
    #                     query = query.filter(RepairRecord.repair_person == repair_person_value)
    #             if repair_caller:
    #                 if isinstance(repair_caller, list):
    #                     repair_caller_value = repair_caller[0] if repair_caller else None
    #                 else:
    #                     repair_caller_value = repair_caller
    #                 if repair_caller_value:
    #                     query = query.filter(RepairRecord.repair_caller == repair_caller_value)
    #             if sort_by:
    #                 for sort_item in sort_by:
    #                     col_id = sort_item['column_id']
    #                     if col_id in ['product_name', 'product_code', 'org_shortname_c', 'department_name', 'report_date', 'repair_status', 'repair_person']:
    #                         direction = sort_item['direction']
    #                         col = getattr(RepairRecord, col_id)
    #                         query = query.order_by(col.asc() if direction == 'asc' else col.desc())
    #                     else:
    #                         print(f"Warning: Invalid sort column ignored: {col_id}")
    #             else:
    #                 query = query.order_by(RepairRecord.report_date.desc())
    #             total_records = query.count()
    #             page_count = (total_records + page_size - 1) // page_size if page_size > 0 else 1
    #             records = query.offset(page_current * page_size).limit(page_size).all()
    #             for r in records:
    #                 data.append({
    #                     'id': r.id,
    #                     'product_id': r.product_id,
    #                     'product_name': r.product_name,
    #                     'org_shortname': r.org_shortname_c,
    #                     'department_name': r.department_name,
    #                     'fault_description': r.fault_description,
    #                     'report_date': r.report_date.strftime('%Y-%m-%d %H:%M:%S') if r.report_date else '',
    #                     'repair_status': r.repair_status,
    #                     'actual_completion_date': r.actual_completion_date,
    #                     'repair_duration': r.repair_duration,
    #                     'repair_person': r.repair_person,
    #                     'repair_company': r.repair_company,
    #                     'repair_type': r.repair_type,
    #                     'repair_content': r.repair_content,
    #                     'repair_cost': r.repair_cost,
    #                     'parts_replaced': r.parts_replaced,
    #                     'repair_result': r.repair_result,
    #                 })
    #         # 按钮可用性逻辑
    #         if active_cell is not None and data:
    #             row = active_cell.get('row', 0)
    #             if 0 <= row < len(data):
    #                 row_data = data[row]
    #                 repair_status = row_data.get('repair_status', '')
    #                 disabled1 = repair_status != '待响应'
    #                 disabled2 = repair_status != '维修中'
    #                 disabled3 = repair_status != '待上传'
    #     except Exception as e:
    #         print(f"!!! ERROR in update_repair_table_and_buttons: {e}")
    #         import traceback
    #         traceback.print_exc()
    #         data = []
    #         page_count = 0
    #         disabled1 = disabled2 = disabled3 = True
    #     return data, page_count, disabled1, disabled2, disabled3

    # 引入Modal组件
    from modules.repair.modals import  register_modal_callbacks

    # 注册Modal相关的回调
    register_modal_callbacks(dash_app)
    
    


    

    # --- 新增：处理 "上传工单" 按钮点击 (仅触发上传组件) ---
    dash_app.clientside_callback(
        """
        function(n_clicks) {
            if (n_clicks > 0) {
                // 查找并点击隐藏的上传组件
                const uploadElement = document.getElementById('upload-work-order');
                if (uploadElement) {
                    uploadElement.click();
                    console.log('Upload component triggered by button click.');
                } else {
                    console.error('Upload component (upload-work-order) not found.');
                }
            }
            return window.dash_clientside.no_update; // 不更新任何输出
        }
        """,
        Output('repair-upload-button', 'id'), # 只是需要一个虚拟输出来挂载回调
        Input('repair-upload-button', 'n_clicks'),
        prevent_initial_call=True
    )


    # --- 修改：处理文件上传的回调 ---
    # 确保它使用正确的 ID 来关联文件
    @dash_app.callback(
        Output('upload-output', 'children'),
        Input('upload-work-order', 'contents'),
        State('upload-work-order', 'filename'),
        State('upload-work-order', 'last_modified'),
        State('repair-details-record-id-store', 'data'), # 从详情内部 Store 获取当前记录 ID
        prevent_initial_call=True
    )
    def update_output(list_of_contents, list_of_names, list_of_dates, record_id): # 参数名修改
        if list_of_contents is not None:
            if not record_id: # 检查是否从 State 获取到了 ID
                 print("Error: No record ID found in repair-details-record-id-store for upload.")
                 # 可以在详情区域显示错误，或者用 action-feedback
                 return html.Div(['错误：未在详情区域找到要关联的维修记录 ID。请先选择一条记录。'], className="text-danger")

            # ... (文件保存逻辑保持不变，使用获取到的 record_id) ...
            content_type, content_string = list_of_contents.split(',')
            decoded = base64.b64decode(content_string)
            try:
                upload_folder = os.path.join(server.root_path, 'uploads', 'work_orders')
                if not os.path.exists(upload_folder):
                    os.makedirs(upload_folder)

                safe_filename = f"repair_{record_id}_{datetime.now().strftime('%Y%m%d%H%M%S')}_{list_of_names}"
                file_path = os.path.join(upload_folder, safe_filename)

                with open(file_path, 'wb') as f:
                    f.write(decoded)

                # (可选) 更新数据库记录
                with server.app_context():
                    record = db.session.query(RepairRecord).get(record_id)
                    if record:
                        # 假设有一个字段存储工单路径列表或最新的工单路径
                        # 例如: record.work_order_path = file_path
                        # 或者 record.work_order_files = (record.work_order_files or []) + [file_path]
                        record.update_time = datetime.now()
                        db.session.commit()
                        print(f"Work order '{safe_filename}' saved for record {record_id}.")
                        return html.Div([f'文件 "{list_of_names}" 已成功上传并关联到记录 {record_id}。'], className="text-success")
                    else:
                        print(f"Error: Record {record_id} not found in DB when saving work order path.")
                        # 文件已保存，但数据库关联失败
                        return html.Div([f'文件 "{list_of_names}" 已上传，但关联到记录 {record_id} 时出错 (记录未找到)。'], className="text-warning")

            except Exception as e:
                print(f"!!! ERROR in update_output (file saving/DB update): {e}")
                return html.Div([f'上传文件 "{list_of_names}" 时出错: {e}'], className="text-danger")
        else:
            # 没有文件内容时不更新
            return dash.no_update

    # @dash_app.callback(
    #     Output('repair-details', 'children'),
    #     Input('repair-records-table', 'selected_rows'),
    #     Input('repair-refresh-flag-answer', 'data'),  # 新增，监听刷新信号
    #     Input('repair-refresh-flag-complete', 'data'),  # 新增，监听刷新信号
    #     Input('repair-refresh-flag-addnew', 'data'),     # <--- 新增，监听刷新信号
    #     Input('repair-refresh-flag-cancel', 'data'),     # <--- 新增，监听刷新信号
    #     State('repair-records-table', 'data')
    # )
    # def update_repair_details(selected_rows, refresh_flag,refresh_flag2,refresh_flag3,refresh_flag4,table_data):
    #     if not selected_rows or not table_data:
    #         return html.P("请在中间列表中选择一条维修记录查看详细信息。", className="text-muted mt-4")
    #     row = selected_rows[0]
    #     record_id = table_data[row]['id']
    #     try:
    #         with server.app_context():
    #             record = db.session.query(RepairRecord).filter_by(id=record_id).first()
    #             if not record:
    #                 return html.P("未找到该维修记录。", className="text-danger mt-4")
    #             record_dict = object_as_dict(record)
    #             return create_details_layout(record_dict)
    #     except Exception as e:
    #         return html.P(f"加载维修详细信息出错: {e}", className="text-danger mt-4")


    # 新增报修Modal：机构-科室联动
    @dash_app.callback(
        Output('new-repair-dept', 'options'),
        Output('new-repair-dept', 'disabled'),
        Output('new-repair-dept', 'value'),
        Input('new-repair-org', 'value')
    )
    def update_new_repair_dept_options(selected_org):
        if selected_org:
            # 查询该机构下的所有科室
            depts = db.session.query(Department).filter(Department.org_name == selected_org, Department.is_active == True).all()
            options = [{"label": d.dept_name, "value": d.dept_name} for d in depts]
            return options, False, None
        return [], True, None

    # 新增报修Modal：科室-设备联动
    @dash_app.callback(
        Output('new-repair-device', 'options'),
        Output('new-repair-device', 'disabled'),
        Output('new-repair-device', 'value'),
        Input('new-repair-dept', 'value'),
        State('new-repair-org', 'value')
    )
    def update_new_repair_device_options(selected_dept, selected_org):
        if selected_org and selected_dept:
            
            # 查询该机构和科室下的所有设备
            devices = db.session.query(Product).filter(
                Product.org_short_name_c == selected_org,
                Product.department_name == selected_dept,
                Product.is_active == 1
            ).all()
            # print(f"p693 Selected Dept: {selected_dept}, Selected Org: {selected_org}")
            # print(f"p693 Devices: {devices}")
            # options = [{"label": d.product_name, "value": d.product_name} for d in devices]
            options = [{"label": f"{d.product_name}（ID:{d.id}）", "value": d.id} for d in devices]
            return options, False, None
        return [], True, None

    @dash_app.callback(
        Output("repair-refresh-flag-addnew", "data", allow_duplicate=True),
        Output("new-repair-modal", "is_open", allow_duplicate=True),
        Output("new-repair-alert", "is_open", allow_duplicate=True),
        Output("new-repair-alert", "children", allow_duplicate=True),
        Input("new-repair-confirm", "n_clicks"),
        State("new-repair-org", "value"),
        State("new-repair-dept", "value"),
        State("new-repair-device", "value"),  # 这里是设备id
        State("new-repair-fault", "value"),
        State("new-repair-caller", "value"),
        prevent_initial_call=True
    )
    def submit_new_repair(n_clicks, org_shortname, dept_name, device_id, fault_desc, caller):
        if not n_clicks:
            raise dash.exceptions.PreventUpdate

        # 校验必填项
        if not (org_shortname and dept_name and device_id and fault_desc and caller):
            return {"refresh": True, "ts": time.time()},True, True, "请填写所有必填项！"

        with server.app_context():
            # 用id查Product
            product = db.session.query(Product).filter(Product.id == device_id, Product.is_active == True).first()
            if not product:
                return {"refresh": True, "ts": time.time()},True, True, "未找到对应设备信息，请检查选择！"
            # 新增：设置设备运行状态为1
            product.running_status = 1
            # 创建维修记录
            new_record = RepairRecord(
                product_id=product.id,
                product_name=product.product_name,
                product_code=product.product_code,
                product_category=product.equipment_category,
                product_brand=product.manufacturer if hasattr(product, "manufacturer") else "",
                product_model=product.model if hasattr(product, "model") else "",
                org_name=product.org_name,
                org_shortname_c=product.org_short_name_c if hasattr(product, "org_short_name_c") else "",
                department_name=product.department_name,
                report_date=datetime.now(),
                repair_caller=caller,
                fault_description=fault_desc,
                repair_status="待响应",
                is_active=True
            )
            db.session.add(new_record)
            db.session.commit()
            # 新增：写入日志
            from flask import session
            from models import User
            user_id = session.get("user_id")
            if user_id:
                user = User.query.get(user_id)
                username = user.username if user else "匿名用户"
            else:
                username = "匿名用户"
            write_repair_log(
                action="网页新建维修",
                username=username,
                device_id=product.id,
                record_id=new_record.id,
                message=f"报修人：{caller}，故障描述: {fault_desc}"
            )
            return {"refresh": True, "ts": time.time()},False, False, ""  # 关闭弹窗，清空提示
   
    @dash_app.callback(
        Output('repair-person-filter', 'options'),
        Output('repair-caller-filter', 'options'),
        Input('repair-filter-button', 'n_clicks'),  # 或者用其它合适的 Input 触发
    )
    def update_person_and_caller_options(n_clicks):
        with server.app_context():
            # 查询所有有效维修人员
            persons = db.session.query(RepairRecord.repair_person).filter(RepairRecord.is_active == 1).distinct().all()
            person_options = [
                {'label': p[0], 'value': p[0]} for p in persons if p[0]
            ]
            # 查询所有有效报修人
            callers = db.session.query(RepairRecord.repair_caller).filter(RepairRecord.is_active == 1).distinct().all()
            caller_options = [
                {'label': c[0], 'value': c[0]} for c in callers if c[0]
            ]
            return person_options, caller_options



    